﻿
namespace BlogEngine.Core.Providers
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Web;
    using System.Xml;

    /// <summary>
    /// A storage provider for BlogEngine that uses XML files.
    ///     <remarks>
    /// To build another provider, you can just copy and modify
    ///         this one. Then add it to the web.config's BlogEngine section.
    ///     </remarks>
    /// </summary>
    public partial class XmlBlogProvider : BlogProvider
    {
        // private static string _Folder = System.Web.HttpContext.Current.Server.MapPath(BlogSettings.Instance.StorageLocation);
        #region Properties

        /// <summary>
        ///     Gets the storage folder of the current blog instance.
        /// </summary>
        //internal string Folder
        //{
        //    get
        //    {
        //        return GetFolder(Blog.CurrentInstance);
        //    }
        //}

        /// <summary>
        ///     Gets the storage folder for the blog.
        /// </summary>
        //internal string GetFolder(Blog blog)
        //{
        //    // if "blog" == null, this means it's the primary instance being asked for -- which
        //    // is in the root of BlogConfig.StorageLocation.
        //    string location = blog == null ? BlogConfig.StorageLocation : blog.StorageLocation;
        //    var p = location.Replace("~/", string.Empty);
        //    return Path.Combine(HttpRuntime.AppDomainAppPath, p);
        //}

        #endregion

        #region Public Methods

        /// <summary>
        /// Deletes a Book from the data store.
        /// </summary>
        /// <param name="Book">
        /// The Book to delete.
        /// </param>
        public override void DeleteBook(Book book)
        {
            var fileName = string.Format("{0}books{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, book.Id);
            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
        }

        /// <summary>
        /// Retrieves all Books from the data store
        /// </summary>
        /// <returns>
        /// List of Books
        /// </returns>
        public override List<Book> FillBooks()
        {
            var folder = this.Folder + "books" + Path.DirectorySeparatorChar;
            var Books = (from file in Directory.GetFiles(folder, "*.xml", SearchOption.TopDirectoryOnly)
                         select new FileInfo(file)
                             into info
                             select info.Name.Replace(".xml", string.Empty)
                                 into id
                                 select Book.Load(new Guid(id))).ToList();

            Books.Sort();
            return Books;
        }

        /// <summary>
        /// Inserts a new Book to the data store.
        /// </summary>
        /// <param name="Book">
        /// The Book to insert.
        /// </param>
        public override void InsertBook(Book book)
        {
            if (!Directory.Exists(string.Format("{0}books", this.Folder)))
            {
                Directory.CreateDirectory(string.Format("{0}books", this.Folder));
            }

            var fileName = string.Format("{0}books{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, book.Id);
            var settings = new XmlWriterSettings { Indent = true };

            var ms = new MemoryStream();

            using (var writer = XmlWriter.Create(ms, settings))
            {
                writer.WriteStartDocument(true);


                writer.WriteStartElement("book");
                writer.WriteElementString("name", book.Name);
                writer.WriteElementString("author", book.Author);
                writer.WriteElementString("picture", book.Picture);
                writer.WriteElementString("publishing", book.Publishing);
                writer.WriteElementString("status", book.Status);
                writer.WriteElementString("summary", book.Summary);
                writer.WriteElementString("comment", book.Comment);
                writer.WriteEndElement();
            }

            using (var fs = File.Open(fileName, FileMode.Create, FileAccess.Write))
            {
                ms.WriteTo(fs);
                ms.Dispose();
            }
        }

        /// <summary>
        /// Retrieves a Book from the provider based on the specified id.
        /// </summary>
        /// <param name="id">
        /// The Book id.
        /// </param>
        /// <returns>
        /// A Book object.
        /// </returns>
        public override Book SelectBook(Guid id)
        {
            var fileName = string.Format("{0}books{1}{2}.xml", this.Folder, Path.DirectorySeparatorChar, id);
            var book = new Book();
            var doc = new XmlDocument();
            doc.Load(fileName);
            book.Name = doc.SelectSingleNode("book/name").InnerText;
            book.Author = doc.SelectSingleNode("book/author").InnerText;
            book.Picture = doc.SelectSingleNode("book/picture").InnerText;
            book.Publishing = doc.SelectSingleNode("book/publishing").InnerText;
            book.Status = doc.SelectSingleNode("book/status").InnerText;
            book.Summary = doc.SelectSingleNode("book/summary").InnerText;
            book.Comment = doc.SelectSingleNode("book/comment").InnerText;

            return book;
        }

        ///// <summary>
        ///// Updates an existing Book in the data store specified by the provider.
        ///// </summary>
        ///// <param name="Book">
        ///// The Book to update.
        ///// </param>
        //public override void UpdateBook(Book Book)
        //{
        //    this.InsertBook(Book);
        //}

        #endregion
    }
}